/** * Copyright 2015 ArcBees Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.arcbees.gaestudio.client.application.visualizer.widget; import javax.inject.Inject; import com.arcbees.analytics.shared.Analytics; import com.arcbees.gaestudio.client.resources.AppResources; import com.google.common.base.Strings; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.BrowserEvents; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONValue; import com.google.gwt.query.client.Function; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FileUpload; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import com.google.inject.assistedinject.Assisted; import static com.arcbees.gaestudio.client.application.analytics.EventCategories.UI_ELEMENTS; import static com.google.gwt.query.client.GQuery.$; public class UploadForm implements IsWidget, FormPanel.SubmitCompleteHandler { public interface Handler { void onFileChosen(String chosenFileName); void onUploadFailure(String errorMessage); void onUploadSuccess(); void onSubmit(); } private static class UploadResponse extends JavaScriptObject { protected UploadResponse() { } public final native boolean isSuccess() /*-{ return this.success; }-*/; public final native String getMessage() /*-{ return this.message; }-*/; } private static final String FILE_UPLOAD = "fileUpload"; private final FileUpload fileUpload = new FileUpload(); private final FormPanel formPanel; private final Handler handler; private final Label selectedFile; private final AppResources resources; private final Analytics analytics; @Inject UploadForm( AppResources resources, Analytics analytics, @Assisted String uploadUrl, @Assisted Handler handler) { this.handler = handler; this.resources = resources; this.analytics = analytics; formPanel = new FormPanel(); selectedFile = new Label("..."); selectedFile.setStyleName(resources.styles().uploadLabel()); fileUpload.setName(FILE_UPLOAD); fileUpload.setVisible(false); formPanel.add(hideFileUploadWithButton("Choose File")); formPanel.setAction(uploadUrl); formPanel.setEncoding(FormPanel.ENCODING_MULTIPART); formPanel.setMethod(FormPanel.METHOD_POST); formPanel.addSubmitCompleteHandler(this); } public boolean hasFileToUpload() { return !Strings.isNullOrEmpty(fileUpload.getFilename()); } @Override public Widget asWidget() { return formPanel; } @Override public void onSubmitComplete(FormPanel.SubmitCompleteEvent event) { handleSubmitComplete(event.getResults()); formPanel.reset(); } public void submit() { if (hasFileToUpload()) { formPanel.submit(); handler.onSubmit(); } } private void handleSubmitComplete(String result) { UploadResponse uploadResponse = getJsonObjectFromHtml(result); if (uploadResponse.isSuccess()) { handler.onUploadSuccess(); } else { handler.onUploadFailure(uploadResponse.getMessage()); } } private Panel hideFileUploadWithButton(String buttonText) { FlowPanel flowPanel = new FlowPanel(); flowPanel.add(fileUpload); Button button = new Button(buttonText, new ClickHandler() { @Override public void onClick(ClickEvent event) { registerFileChangedHandler(); $(fileUpload).click(); analytics.sendEvent(UI_ELEMENTS, "click") .eventLabel("Visualizer -> Upload Form -> Choose File") .go(); } }); button.setStyleName(resources.styles().button()); button.addStyleName(resources.styles().chooseFileButton()); flowPanel.add(selectedFile); flowPanel.add(button); return flowPanel; } private void registerFileChangedHandler() { $(fileUpload.getElement()).unbind(BrowserEvents.CHANGE); $(fileUpload.getElement()).change(new Function() { @Override public void f() { String path = fileUpload.getFilename(); String fileName = extractFileNameFromPath(path); selectedFile.setText(fileName); handler.onFileChosen(fileName); } }); } private String extractFileNameFromPath(String path) { Integer lastIndex = path.replace("\\", "/").lastIndexOf("/"); return path.substring(lastIndex + 1); } private UploadResponse getJsonObjectFromHtml(String result) { HTML htmlParser = new HTML(result); String json = htmlParser.getText().trim(); JSONValue jsonValue = JSONParser.parseStrict(json); JSONObject object = jsonValue.isObject(); return object.getJavaScriptObject().cast(); } }